from mime import structure, convert_to_log, message_from_string, save_message
from xml.dom.minidom import parseString
import time
from gevent import sleep
from utils import GClient, WSGIServerLog, render, config

class Mm7Server(WSGIServerLog):
	def __init__(self, addr = '', port = 8877, pool=None, name='MM7Server'):
		WSGIServerLog.__init__(self, (addr, port), self.application)
		self.name = name
		self.set_spawn(pool)

	def application(self, env, start_response):
		if env['PATH_INFO'] == '/mm7':
			length = int(env['CONTENT_LENGTH'])
			host = env['REMOTE_ADDR']
			self._log('got request from %s' % host)
			data = env['wsgi.input'].read(length)
			self.log_debug(data)
			#self._log('get:\n' + data)
			x1 = data.find('<?xml')
			x2 = data.find('lope>', x1)
			x3 = data.find('Cont', x2)
			m = message_from_string(data[x3:], True)
			if self.save:
				save_message(m, '%s/%s/%s' % (config.main.work_dir, self.name, str(time.time())))
			convert_to_log(m)
			self._log(m.as_string())
			self._log('struct:\n%s' % structure(m))
			mm7_xml = parseString(data[x1:x2 + 5])
			cNodes = mm7_xml.childNodes
			transId = cNodes[0].getElementsByTagName('mm7:TransactionID')[0].childNodes[0].toxml()
			recipient = cNodes[0].getElementsByTagName('Recipients')[0].childNodes[0].childNodes[0].childNodes[0].toxml()
			deliveryReport = cNodes[0].getElementsByTagName('DeliveryReport')[0].childNodes[0].toxml()
			self._log('DeliveryReport: %s' % deliveryReport)
			msgId = 'mm7.'+ "%.5f" % time.time()
			if self.responseDelay is not None:
				sleep(self.responseDelay)
			start_response('200 OK', [('Content-Type', 'text/xml')])
			self._log('send:\n' + str(render.mm7_resp_template(self.returnedStatus , transId, msgId)))
			if self.deliveryReport == True and self.returnedStatus == '1000' and deliveryReport == 'true':
				self.pool.spawn(self.dr, host, transId, msgId, recipient)
			return [str(render.mm7_resp_template(self.returnedStatus , transId, msgId))]
		else:
			start_response('404 Not Found', [('Content-Type', 'text/html')])
			return ['<h1>Not Found</h1>']

	def dr(self, host, transId, msgId, recipient):
		# I know that should be queue not new thread for new DR but it's only test server
		if self.deliveryReportDelay is not None:
			sleep(self.deliveryReportDelay)
		if self.deliveryReportIP != 'fromRequest':
			host = self.deliveryReportIP
		dr_xml = render.mm7_delivery_report_template(self.deliveryReportStatus, \
							     transId, msgId, recipient, \
							     self.deliveryReportShortCode, \
							     self.deliveryReportStatusText)
		dr_html = str(render.mm7_http(host, len(str(dr_xml)), dr_xml))
		self._log(self.deliveryReportPort)
		self._log('send delivery report to %s:%d' % (host, self.deliveryReportPort))
		self._log(dr_html)
		c = GClient(self.pool, host, self.deliveryReportPort)
		r = c.connect()
		self.loga(r)
		r = c.send_sync(dr_html)
		self.loga(r)
